// SPDX-License-Identifier: GPL-2.0
/*
 * COMPLETE
 *
 * (C) 2024.05.20 BiscuitOS <buddy.zhang@aliyun.com>
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/delay.h> 
#include <linux/completion.h>

static struct task_struct *producer, *consumer;
/* DECLARE COMPLETION */
static DECLARE_COMPLETION(BiscuitOS_complection);

static int producer_kfn(void *data)
{
	printk("PRODUCER KTHREAD RUNNING.\n");

	/* KTHREAD MAIN ROUTE */
	while (!kthread_should_stop()) {
		ssleep(3);
		/* SETUP COMPLECTION */
		complete(&BiscuitOS_complection);
	}

	printk("PRODUCER KTHREAD STOPING\n");

	return 0;
}

static int consumer_kfn(void *data)
{
	printk("CONSUMER KTHREAD RUNNING.\n");

	/* KTHREAD MAIN ROUTE */
	while (!kthread_should_stop()) {
		/* WAIT COMPLETION */
		wait_for_complete(&BiscuitOS_complection);

		printk("CONSUMER: HIT\n");
		ssleep(1);
		/* RESET COMPLECTION */
		init_complete(&BiscuitOS_complection);
	}

	printk("CONSUMER KTHREAD STOPING\n");

	return 0;
}

static int __init BiscuitOS_init(void)
{
	/* CREATE AND RUNNING PRODUCER KTHREAD */
	producer = kthread_run(producer_kfn, NULL, "BiscuitOS-producer");
	if (IS_ERR(producer))
		return PTR_ERR(producer);

	/* CREATE AND RUNNING CONSUMER KTHREAD */
	consumer = kthread_run(consumer_kfn, NULL, "BiscuitOS-consumer");
	if (IS_ERR(consumer))
		return PTR_ERR(consumer);

	return 0;
}

static void __exit BiscuitOS_exit(void)
{
	/* KTHREAD STOP */
	kthread_stop(consumer);
	kthread_stop(producer);
}

module_init(BiscuitOS_init);
module_exit(BiscuitOS_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("BiscuitOS <buddy.zhang@aliyun.com>");
MODULE_DESCRIPTION("BiscuitOS SCHEDULE SUBSYSTEM");
